#include "timer_wheel.hpp"
#include <algorithm>

namespace timeout_manager {

TimerWheel::TimerWheel(size_t wheelSize, Duration tickDuration)
    : wheelSize_(wheelSize), 
      tickDuration_(tickDuration),
      wheel_(wheelSize),           // 初始化wheelSize个空的vector
      running_(false), 
      currentSlot_(0) {
    
    std::cout << "创建时间轮: 大小=" << wheelSize 
              << ", 间隔=" << tickDuration.count() << "ms" << " (TimerWheel::TimerWheel)"<<std::endl;
    
    startTime_ = std::chrono::steady_clock::now();
}

TimerWheel::~TimerWheel() {
    stop();
    std::cout << "时间轮已销毁" << " (TimerWheel::~TimerWheel)"<<std::endl;
}

void TimerWheel::addTimer(uint64_t taskId, Duration timeout, TimeoutCallback callback) {
    // 计算任务的过期时间点
    auto expireTime = std::chrono::steady_clock::now() + timeout;
    
    // 计算应该放在哪个槽位
    size_t slot = getSlot(expireTime);
    
    std::cout << "添加定时任务 ID=" << taskId 
              << ", 超时=" << timeout.count() << "ms"
              << ", 槽位=" << slot << " (TimerWheel::addTimer)" << std::endl;
    
    // 加锁保护时间轮
    std::lock_guard<std::mutex> lock(wheelMutex_);
    
    // 将任务添加到对应槽位
    wheel_[slot].emplace_back(taskId, expireTime, std::move(callback));
    
    // 在快速查找表中记录任务位置
    taskSlotMap_[taskId] = slot;
}

bool TimerWheel::removeTimer(uint64_t taskId) {
    std::lock_guard<std::mutex> lock(wheelMutex_);
    
    // 在快速查找表中查找任务
    auto it = taskSlotMap_.find(taskId);
    if (it == taskSlotMap_.end()) {
        std::cout << "删除定时任务失败，任务不存在: ID=" << taskId <<" (TimerWheel::removeTimer)"<< std::endl;
        return false;
    }
    
    size_t slot = it->second;
    auto& tasks = wheel_[slot];
    
    // 在对应槽位中删除任务
    auto taskIt = std::find_if(tasks.begin(), tasks.end(),
        [taskId](const TimerTask& task) { return task.id == taskId; });
    
    if (taskIt != tasks.end()) {
        tasks.erase(taskIt);
        taskSlotMap_.erase(it);
        std::cout << "成功删除定时任务: ID=" << taskId  <<" (TimerWheel::removeTimer)"<< std::endl;
        return true;
    }
    
    std::cout << "删除定时任务失败，任务在槽位中不存在: ID=" << taskId  <<" (TimerWheel::removeTimer)"<< std::endl;
    return false;
}

void TimerWheel::start() {
    if (running_.load()) {
        std::cout << "时间轮已经在运行中" <<" (TimerWheel::start)" <<std::endl;
        return;
    }
    
    std::cout << "启动时间轮..."  <<" (TimerWheel::start)"<< std::endl;
    running_.store(true);
    startTime_ = std::chrono::steady_clock::now();
    
    // 创建并启动时间轮线程
    timerThread_ = std::thread([this] { timerThreadFunc(); });
}

void TimerWheel::stop() {
    if (!running_.load()) {
        return;
    }
    
    std::cout << "停止时间轮..." <<" (TimerWheel::stop)"<< std::endl;
    running_.store(false);
    
    // 等待线程结束
    if (timerThread_.joinable()) {
        timerThread_.join();
    }
    
    std::cout << "时间轮已停止" <<" (TimerWheel::stop)"<< std::endl;
}

TimerWheel::Statistics TimerWheel::getStatistics() const {
    std::lock_guard<std::mutex> lock(wheelMutex_);
    
    size_t activeTimers = 0;
    for (const auto& slot : wheel_) {
        activeTimers += slot.size();
    }
    
    return {
        wheelSize_,
        activeTimers,
        currentSlot_.load()
    };
}

// void TimerWheel::timerThreadFunc() {
//     std::cout << "时间轮线程启动" << std::endl;
    
//     while (running_.load()) {
//         // 计算下一次tick的时间点
//         auto nextTick = startTime_ + tickDuration_ * (currentSlot_.load() + 1);
        
//         // 等待到下一个tick时间
//         std::this_thread::sleep_until(nextTick);
        
//         // 检查是否需要停止
//         if (!running_.load()) break;
        
//         // 处理当前槽位的过期任务
//         size_t currentSlot = currentSlot_.load();
//         processExpiredTasks(currentSlot);
        
//         // 移动到下一个槽位（循环）
//         currentSlot_.store((currentSlot + 1) % wheelSize_);
        
//         if (currentSlot % 10 == 0) {  // 每10个tick打印一次状态
//             auto stats = getStatistics();
//             std::cout << "时间轮状态: 槽位=" << stats.currentSlot 
//                       << ", 活跃定时器=" << stats.activeTimers << std::endl;
//         }
//     }
    
//     std::cout << "时间轮线程退出" << std::endl;
// }


void TimerWheel::timerThreadFunc() {
    std::cout << "时间轮线程启动" << " (TimerWheel::timerThreadFunc)"<<std::endl;

    // 用于记录tick的全局计数
    uint64_t tickCount = 0;

    while (running_.load()) {
        // 计算下一次tick的时间点
        auto nextTick = startTime_ + tickDuration_ * (tickCount + 1);
        // 等待到下一个tick时间
        std::this_thread::sleep_until(nextTick);
        
        // 检查是否需要停止
        if (!running_.load()) break;

        size_t slot = tickCount % wheelSize_; // 计算当前处理槽
        // 处理当前槽位的过期任务
        processExpiredTasks(slot);
        // 当前要处理的过期槽位（刚刚过期）
        currentSlot_.store(slot);

        tickCount++;

        if (slot % 10 == 0) {
            auto stats = getStatistics();
            std::cout << "时间轮状态: 槽位=" << stats.currentSlot
                      << ", 活跃定时器=" << stats.activeTimers << " (TimerWheel::timerThreadFunc)"<< std::endl;
            // 打印当前时间戳
            // printCurrentTime();
        }
    }

    std::cout << "时间轮线程退出" << " (TimerWheel::timerThreadFunc)"<< std::endl;
}

void TimerWheel::processExpiredTasks(size_t slot) {
    std::vector<TimerTask> expiredTasks;
    auto now = std::chrono::steady_clock::now();
    
    // 加锁获取过期任务
    {
        std::lock_guard<std::mutex> lock(wheelMutex_);
        auto& tasks = wheel_[slot];
        
        // 找出真正过期的任务（可能有任务被放错槽位）
        for (auto it = tasks.begin(); it != tasks.end(); ) {
            if (it->expireTime <= now) {
                expiredTasks.push_back(std::move(*it));
                taskSlotMap_.erase(it->id);  // 从快速查找表中删除
                it = tasks.erase(it);        // 从槽位中删除
                // 打印
                std::cout << "删除过期任务: ID=" << it->id <<"(TimerWheel::processExpiredTasks)" << std::endl;
            } else {
                ++it;
            }
        }
    }
    
    // 在锁外执行回调函数，避免阻塞时间轮
    // std::cout << "expiredTasks.size(): " << expiredTasks.size() << std::endl;
    // // 打印槽位
    // std::cout << "expiredTasks slot: " << slot << std::endl;
    for (auto& task : expiredTasks) {
        std::cout << "触发超时任务: ID=" << task.id <<"(TimerWheel::processExpiredTasks)"<< std::endl;
        try {
            if (task.callback) {
                task.callback();
            }
        } catch (const std::exception& e) {
            std::cout << "超时回调执行异常: " << e.what() <<"(TimerWheel::processExpiredTasks)"<< std::endl;
        } catch (...) {
            std::cout << "超时回调执行未知异常" <<"(TimerWheel::processExpiredTasks)"<< std::endl;
        }
    }
}

size_t TimerWheel::getSlot(TimePoint expireTime) const {
    // 计算从启动时间到过期时间的间隔
    auto duration = expireTime - startTime_;
    
    // 将间隔转换为tick数量
    auto ticks = std::chrono::duration_cast<std::chrono::milliseconds>(duration) / tickDuration_;
    
    // 计算对应的槽位（取模运算，实现循环）
    return static_cast<size_t>(ticks) % wheelSize_;
}




















// 在 timer_wheel.cpp 中添加实现

void TimerWheel::printAllSlots(bool showEmptySlots, int detailLevel) const {
    std::lock_guard<std::mutex> lock(wheelMutex_);
    
    auto now = std::chrono::steady_clock::now();
    auto timeSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - startTime_);
    
    std::cout << "\n" << std::string(80, '=') << std::endl;
    std::cout << "时间轮状态报告" << std::endl;
    std::cout << std::string(80, '=') << std::endl;
    std::cout << "时间轮大小: " << wheelSize_ << " 槽位" << std::endl;
    std::cout << "Tick间隔: " << tickDuration_.count() << "ms" << std::endl;
    std::cout << "当前槽位: " << currentSlot_.load() << std::endl;
    std::cout << "运行状态: " << (running_.load() ? "运行中" : "已停止") << std::endl;
    std::cout << "当前时间距启动: " << timeSinceStart.count() << "ms" << std::endl;
    
    // 统计信息
    size_t totalTasks = 0;
    size_t expiredTasks = 0;
    size_t activeSlotsCount = 0;
    
    // 先统计
    for (size_t i = 0; i < wheelSize_; ++i) {
        const auto& tasks = wheel_[i];
        if (!tasks.empty()) {
            activeSlotsCount++;
            totalTasks += tasks.size();
            
            for (const auto& task : tasks) {
                if (task.expireTime <= now) {
                    expiredTasks++;
                }
            }
        }
    }
    
    std::cout << "总任务数: " << totalTasks << std::endl;
    std::cout << "已过期任务: " << expiredTasks << std::endl;
    std::cout << "活跃槽位数: " << activeSlotsCount << " / " << wheelSize_ << std::endl;
    std::cout << std::string(80, '-') << std::endl;
    
    // 详细显示每个槽位
    for (size_t i = 0; i < wheelSize_; ++i) {
        const auto& tasks = wheel_[i];
        
        // 跳过空槽位（如果不需要显示的话）
        if (tasks.empty() && !showEmptySlots) {
            continue;
        }
        
        // 槽位标题
        std::string slotHeader = "槽位 " + std::to_string(i);
        if (i == currentSlot_.load()) {
            slotHeader += " [当前]";
        }
        slotHeader += " (" + std::to_string(tasks.size()) + " 个任务)";
        
        std::cout << slotHeader << std::endl;
        
        if (tasks.empty()) {
            std::cout << "  (空)" << std::endl;
        } else {
            // 按过期时间排序显示
            std::vector<std::reference_wrapper<const TimerTask>> sortedTasks(tasks.begin(), tasks.end());
            std::sort(sortedTasks.begin(), sortedTasks.end(), 
                [](const TimerTask& a, const TimerTask& b) {
                    return a.expireTime < b.expireTime;
                });
            
            for (const auto& taskRef : sortedTasks) {
                const auto& task = taskRef.get();
                printTaskInfo(task, now, timeSinceStart, detailLevel);
            }
        }
        std::cout << std::endl;
    }
    
    std::cout << std::string(80, '=') << std::endl;
}

void TimerWheel::printSlot(size_t slot) const {
    if (slot >= wheelSize_) {
        std::cout << "错误: 槽位 " << slot << " 超出范围 [0, " << wheelSize_ - 1 << "]" << std::endl;
        return;
    }
    
    std::lock_guard<std::mutex> lock(wheelMutex_);
    
    auto now = std::chrono::steady_clock::now();
    auto timeSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - startTime_);
    
    const auto& tasks = wheel_[slot];
    
    std::cout << "\n槽位 " << slot;
    if (slot == currentSlot_.load()) {
        std::cout << " [当前槽位]";
    }
    std::cout << " - " << tasks.size() << " 个任务:" << std::endl;
    
    if (tasks.empty()) {
        std::cout << "  (空)" << std::endl;
        return;
    }
    
    for (const auto& task : tasks) {
        printTaskInfo(task, now, timeSinceStart, 2);  // 使用详细级别
    }
}

// 辅助函数：打印单个任务信息
void TimerWheel::printTaskInfo(const TimerTask& task, 
                              std::chrono::steady_clock::time_point now,
                              std::chrono::milliseconds timeSinceStart,
                              int detailLevel) const {
    
    auto expireTimeSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(
        task.expireTime - startTime_);
    auto timeToExpire = std::chrono::duration_cast<std::chrono::milliseconds>(
        task.expireTime - now);
    
    bool isExpired = task.expireTime <= now;
    
    std::cout << "  ├─ 任务ID: " << task.id;
    
    if (isExpired) {
        std::cout << " [已过期]";
    }
    std::cout << std::endl;
    
    if (detailLevel >= 1) {
        std::cout << "  │  预期过期时间: " << expireTimeSinceStart.count() << "ms (距启动)" << std::endl;
        std::cout << "  │  当前时间: " << timeSinceStart.count() << "ms (距启动)" << std::endl;
        
        if (isExpired) {
            auto overdue = timeSinceStart - expireTimeSinceStart;
            std::cout << "  │  已过期: " << overdue.count() << "ms" << std::endl;
        } else {
            std::cout << "  │  剩余时间: " << timeToExpire.count() << "ms" << std::endl;
        }
    }
    
    if (detailLevel >= 2) {
        // 计算任务应该在哪个tick被处理
        auto ticksToExpire = expireTimeSinceStart.count() / tickDuration_.count();
        auto expectedSlot = ticksToExpire % wheelSize_;
        
        std::cout << "  │  预期tick: " << ticksToExpire << std::endl;
        std::cout << "  │  预期槽位: " << expectedSlot << std::endl;
        std::cout << "  │  实际槽位: " << getCurrentSlotForTask(task.id) << std::endl;
        std::cout << "  │  回调地址: " << (task.callback ? "有效" : "无效") << std::endl;
    }
}

// 辅助函数：获取任务当前所在的槽位
size_t TimerWheel::getCurrentSlotForTask(uint64_t taskId) const {
    auto it = taskSlotMap_.find(taskId);
    return (it != taskSlotMap_.end()) ? it->second : SIZE_MAX;
}
} // namespace timeout_manager